#lang racket

;(define (make-mobile left right)
;  (list left right))

;(define (make-branch length structure)
;  (list length structure))

;----------------------------------------------------------------------------------------------
;a

;(define (left-branch mobile)
;  (car mobile))

;(define (right-branch mobile)
;  (car (cdr mobile)))

;(define (branch-length branch)
;  (car branch))

;(define (branch-structure branch)
;  (car (cdr branch)))

;----------------------------------------------------------------------------------------------
;d

(define (make-mobile left right)
  (cons left right))

(define (make-branch length structure)
  (cons length structure))

(define (left-branch mobile)
  (car mobile))

(define (right-branch mobile)
  (cdr mobile))

(define (branch-length branch)
  (car branch))

(define (branch-structure branch)
  (cdr branch))

(define mobile1 (make-mobile (make-branch 10 1) (make-branch 10 1)))

;(branch-structure (left-branch mobile1))

;----------------------------------------------------------------------------------------------
;b

(define (total-weight mobile)
  (let ((left-struc  (branch-structure (left-branch  mobile)))
        (right-struc (branch-structure (right-branch mobile))))
    (let ((left-weight (if (pair? left-struc)
                         (total-weight left-struc)
                         left-struc))
        (right-weight (if (pair? right-struc)
                          (total-weight right-struc)
                          right-struc)))
      (+ left-weight right-weight))))

(define mobile2 (make-mobile (make-branch 10 3) (make-branch 9 4)))

(define mobile3 (make-mobile (make-branch 10 mobile1) (make-branch 9 mobile2)))

;(total-weight mobile3)

;----------------------------------------------------------------------------------------------
;c

(define (balanced? mobile)
  (let ((left-length  (branch-length (left-branch  mobile)))
        (right-length (branch-length (right-branch mobile)))
        (left-struct  (branch-structure (left-branch  mobile)))
        (right-struct (branch-structure (right-branch mobile))))
    (let ((left-balance  (if (pair?  left-struct)
                             (balanced?  left-struct)
                             true))
          (right-balance (if (pair? right-struct)
                             (balanced? right-struct)
                             true))
          (left-weight  (if (pair? left-struct)
                            (total-weight left-struct)
                            left-struct))
          (right-weight (if (pair? left-struct)
                            (total-weight right-struct)
                            right-struct)))
      (and left-balance right-balance (= (* left-length left-weight)
                                         (* right-length right-weight))))))

(balanced? mobile2)
